<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是学习uboot顶层Makefile的相关笔记。若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV05-01-uboot-06-顶层Makefile-02-相关过程分析">
<meta property="og:url" content="https://sumumm.github.io/post/5c91070d.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是学习uboot顶层Makefile的相关笔记。若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730122233164.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730122747654.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730123504197.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730133422636.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730133624015.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730134520374.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730134805520.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135048080.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135331282.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135605771.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135721373.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140006404.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140144991.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140440227.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140953313.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141035174.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141153467.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141403808.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141540677.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142244988.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142326658.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142402882.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142755244.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143037482.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143302250.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143707862.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143850408.png">
<meta property="article:published_time" content="2023-09-08T11:23:01.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:57.041Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="(ALPHA)LV05-uboot与内核">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730122233164.png">


<link rel="canonical" href="https://sumumm.github.io/post/5c91070d.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://sumumm.github.io/post/5c91070d.html","path":"post/5c91070d.html","title":"LV05-01-uboot-06-顶层Makefile-02-相关过程分析"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV05-01-uboot-06-顶层Makefile-02-相关过程分析 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81make-xxx-defconfig-%E8%BF%87%E7%A8%8B"><span class="nav-text">一、make xxx_defconfig 过程  </span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E9%A1%B6%E5%B1%82Makefile%E5%86%85%E5%AE%B9"><span class="nav-text">1. 顶层Makefile内容</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-1-422-437%E8%A1%8C"><span class="nav-text">1.1 422~437行</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-2-439-446%E8%A1%8C"><span class="nav-text">1.2 439~446行</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-3-448-527%E8%A1%8C"><span class="nav-text">1.3 448~527行</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-Makefile-build-%E8%84%9A%E6%9C%AC%E5%88%86%E6%9E%90"><span class="nav-text">2. Makefile.build 脚本分析  </span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-scripts-basic-%E7%9B%AE%E6%A0%87%E5%AF%B9%E5%BA%94%E7%9A%84%E5%91%BD%E4%BB%A4"><span class="nav-text">2.1  scripts_basic 目标对应的命令  </span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-1-1-8-17%E8%A1%8C"><span class="nav-text">2.1.1 8~17行</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-1-2-56-59%E8%A1%8C"><span class="nav-text">2.1.2 56~59行</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-1-3-116-119%E8%A1%8C"><span class="nav-text">2.1.3 116~119行</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-config-%E7%9B%AE%E6%A0%87%E5%AF%B9%E5%BA%94%E7%9A%84%E5%91%BD%E4%BB%A4"><span class="nav-text">2.2 %config 目标对应的命令  </span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E8%BF%87%E7%A8%8B%E6%80%BB%E7%BB%93"><span class="nav-text">3. 过程总结</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81-make%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90"><span class="nav-text">二、 make过程分析</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E7%9B%AE%E6%A0%87"><span class="nav-text">1. 目标</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-u-boot-bin"><span class="nav-text">2. u-boot.bin</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-u-boot-nodtb-bin"><span class="nav-text">3. u-boot-nodtb.bin</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E8%BF%87%E7%A8%8B%E6%80%BB%E7%BB%93"><span class="nav-text">4. 过程总结</span></a></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/5c91070d.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV05-01-uboot-06-顶层Makefile-02-相关过程分析 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV05-01-uboot-06-顶层Makefile-02-相关过程分析
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-09-08 19:23:01" itemprop="dateCreated datePublished" datetime="2023-09-08T19:23:01+08:00">2023-09-08</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/" itemprop="url" rel="index"><span itemprop="name">02IMX6ULL平台</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/" itemprop="url" rel="index"><span itemprop="name">LV05-uboot与内核</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>6.8k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>25 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是学习uboot顶层Makefile的相关笔记。若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" width=150px>Windows版本</td>        <td align="left">windows11</td>    </tr>    <tr>        <td align="center">Ubuntu版本</td>        <td align="left">Ubuntu16.04的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 16 Pro</td>        <td align="left">16.2.3 build-19376536</td>      </tr>    <tr>        <td align="center">终端软件</td>        <td align="left">MobaXterm(Professional Edition v23.0 Build 5042 (license))</td>      </tr>    <tr>        <td align="center">Linux开发板</td>        <td align="left">正点原子 i.MX6ULL Linux 阿尔法开发板</td>      </tr>    <tr>        <td align="center">uboot</td>        <td align="left">NXP官方提供的uboot，NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)</td>      </tr>    <tr>        <td align="center">linux内核</td>        <td align="left">linux-4.15(NXP官方提供)</td>      </tr>    <tr>        <td align="center">Win32DiskImager</td>        <td align="left">Win32DiskImager v1.0</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center">分类</td>        <td align="center">网址</td>        <td align="center">说明</td>    </tr>    <tr>        <td align="center" rowspan="5">官方网站</td>        <td align="left"><a href="https://www.arm.com/" target="_blank">https://www.arm.com/</a></td>        <td align="left">ARM官方网站，在这里我们可以找到Cotex-Mx以及ARMVx的一些文档</td>    </tr>    <tr>        <td align="left"><a href="https://www.nxp.com.cn/" target="_blank">https://www.nxp.com.cn/ </a></td>        <td align="left">NXP官方网站</td>    </tr>    <tr>        <td align="left"><a href="https://www.nxpic.org.cn/" target="_blank">https://www.nxpic.org.cn/</a></td><td align="left">NXP 官方社区</td>    </tr>    <tr>        <td align="left"><a href="https://u-boot.readthedocs.io/en/latest/" target="_blank">https://u-boot.readthedocs.io/en/latest/</a></td><td align="left">u-boot官网</td>    </tr>    <tr>        <td align="left"><a href="https://www.kernel.org/" target="_blank">https://www.kernel.org/</a></td><td align="left">linux内核官网</td>    </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center">分类</td>        <td align="center">网址</td>        <td align="center">说明</td>    </tr>    <tr>        <td align="center" rowspan="4">NXP</td>        <td align="left"><a href="https://github.com/nxp-imx" target="_blank">https://github.com/nxp-imx</a></td>        <td align="left">NXP imx开发资源GitHub组织，里边会有u-boot和linux内核的仓库</td>    </tr>    <tr>        <td align="left"><a href="https://elixir.bootlin.com/linux/latest/source" target="_blank">https://elixir.bootlin.com/linux/latest/source</a></td>        <td align="left">在线阅读linux kernel源码</td>    </tr>    <tr>        <td align="left"><a href="https://github.com/nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga" target="_blank">nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga</a></td>        <td align="left">NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga</td>    </tr>    <tr>        <td align="left"><a href="https://github.com/nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga" target="_blank">nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga</a></td>        <td align="left">NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga</td>    </tr>    <tr>        <td align="center" rowspan="2">I.MX6ULL</td>        <td align="left"><a href="https://www.nxp.com.cn/docs/en/data-sheet/IMX6ULLIEC.pdf" target="_blank">i.MX 6ULL Applications Processors for Industrial Products</a></td>        <td align="left">I.MX6ULL 芯片手册（datasheet，可以在线查看）</td>    </tr>    <tr>        <td align="left"><a href="https://www.nxp.com.cn/webapp/Download?colCode=IMX6ULLRM&lang_cd=zh" target="_blank">i.MX 6ULL Applications ProcessorReference Manual</a></td>        <td align="left">I.MX6ULL 参考手册（下载后才能查看，需要登录NXP官网）</td>    </tr></table>
              </div>
            </details>

<h1 id="一、make-xxx-defconfig-过程"><a href="#一、make-xxx-defconfig-过程" class="headerlink" title="一、make xxx_defconfig 过程  "></a><font size=3>一、make xxx_defconfig 过程  </font></h1><p>在编译 uboot 之前要使用“make xxx_defconfig”命令来配置 uboot，那么这个配置过程是如何运行的呢？  </p>
<h2 id="1-顶层Makefile内容"><a href="#1-顶层Makefile内容" class="headerlink" title="1. 顶层Makefile内容"></a><font size=3>1. 顶层Makefile内容</font></h2><h3 id="1-1-422-437行"><a href="#1-1-422-437行" class="headerlink" title="1.1 422~437行"></a><font size=3>1.1 422~437行</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730122233164.png" alt="image-20230730122233164" style="zoom:50%;" />

<p>第 422 行定义了变量 version_h，这变量保存版本号文件，此文件是自动生成的。文件 include&#x2F;generated&#x2F;version_autogenerated.h（编译后才会生成）内容如下所示：  </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> PLAIN_VERSION <span class="string">&quot;2016.03-g7fd772f&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_VERSION <span class="string">&quot;U-Boot &quot;</span> PLAIN_VERSION</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> CC_VERSION_STRING <span class="string">&quot;arm-linux-gnueabihf-gcc (Linaro GCC 4.9-2017.01) 4.9.4&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> LD_VERSION_STRING <span class="string">&quot;GNU ld (Linaro_Binutils-2017.01) 2.24.0.20141017 Linaro 2014_11-3-git&quot;</span></span></span><br></pre></td></tr></table></figure>

<p>第 423 行定义了变量 timestamp_h，此变量保存时间戳文件，此文件也是自动生成的。文件include&#x2F;generated&#x2F;timestamp_autogenerated.h 内容如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_DATE <span class="string">&quot;Jul 30 2023&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_TIME <span class="string">&quot;12:23:59&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_TZ <span class="string">&quot;+0800&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_DMI_DATE <span class="string">&quot;07/30/2023&quot;</span></span></span><br></pre></td></tr></table></figure>

<p>第 425 行定义了变量 no-dot-config-targets。</p>
<p>第 429 行定义了变量 config-targets，初始值为 0。</p>
<p>第 430 行定义了变量 mixed-targets，初始值为 0。  </p>
<p>第 431 行定义了变量 dot-config，初始值为 1。</p>
<p>第 433 行将 MAKECMDGOALS 中不符合 no-dot-config-targets 的部分过滤掉，剩下的如果不为空的话条件就成立。 MAKECMDGOALS 是 make 的一个环境变量，这个变量会保存我们所指定的终极目标列表，比如执行“make mx6ull_14x14_evk_emmc_defconfig”，那么 MAKECMDGOALS就为mx6ull_14x14_evk_emmc_defconfig。很明显过滤后为空，所以条件不成立，变量 dot-config 依旧为 1。</p>
<h3 id="1-2-439-446行"><a href="#1-2-439-446行" class="headerlink" title="1.2 439~446行"></a><font size=3>1.2 439~446行</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730122747654.png" alt="image-20230730122747654" style="zoom:50%;" />

<p>第439行判断KBUILD_EXTMOD是否为空，如果KBUILD_EXTMOD为空的话条件成立，经过前面的分析，我们知道 KBUILD_EXTMOD 为空，所以条件成立。</p>
<p>第 440 行将 MAKECMDGOALS 中不符合“config”和“%config”的部分过滤掉，如果剩下的部分不为空条件就成立，很明显此处条件成立，变量 config-targets&#x3D;1。</p>
<p>第 442 行统计 MAKECMDGOALS 中的单词个数，如果不为 1 的话条件成立。此处调用Makefile 中的 words 函数来统计单词个数， words 函数格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(words &lt;text&gt;)</span></span><br></pre></td></tr></table></figure>

<p>很明显， MAKECMDGOALS 的单词个数是 1 个，所以条件不成立， mixed-targets 继续为0。综上所述，这些变量值如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">config-targets = 1</span><br><span class="line">mixed-targets = 0</span><br><span class="line">dot-config = 1</span><br></pre></td></tr></table></figure>

<h3 id="1-3-448-527行"><a href="#1-3-448-527行" class="headerlink" title="1.3 448~527行"></a><font size=3>1.3 448~527行</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730123504197.png" alt="image-20230730123504197" style="zoom:50%;" />

<p>第 448 行如果变量 mixed-targets 为 1 的话条件成立，很明显，条件不成立。</p>
<p>第 465 行如果变量 config-targets 为 1 的话条件成立，很明显，条件成立，执行这个分支。</p>
<p>第 473 行，没有目标与之匹配，所以不执行。    </p>
<p>第 476 行，有目标与之匹配，当输入“make xxx_defconfig”的时候就会匹配到%config 目标，目标“%config”依赖于 scripts_basic、 outputmakefile 和 FORCE。 FORCE 在顶层 Makefile的 1610 行有如下定义：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">PHONY += FORCE</span><br><span class="line"><span class="section">FORCE:</span></span><br></pre></td></tr></table></figure>

<p>可以看出 FORCE 是没有规则和依赖的，所以每次都会重新生成 FORCE。当 FORCE 作为其他目标的依赖时，由于 FORCE 总是被更新过的，因此依赖所在的规则总是会执行的。</p>
<details class="folding-tag" blue><summary> scripts_basic 和 outputmakefile </summary>
              <div class='content'>
              <p>依赖 scripts_basic 和 outputmakefile 在顶层 Makefile 中的内容如下  </p><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730133422636.png" alt="image-20230730133422636" style="zoom:50%;" /><p>第 408 行，判断 KBUILD_SRC 是否为空，只有变量 KBUILD_SRC 不为空的时候outputmakefile 才有意义，经过我们前面的分析 KBUILD_SRC 为空，所以 outputmakefile 无效。只有 scripts_basic 是有效的。  </p><p>第 396~398 行是 scripts_basic 的规则，其对应的命令用到了变量 Q、 MAKE 和 build，其中：  </p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Q=@或为空</span><br><span class="line">MAKE=make</span><br></pre></td></tr></table></figure><p>变量 build 是在 scripts&#x2F;Kbuild.include 文件中有定义，定义如下：  </p><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730133624015.png" alt="image-20230730133624015" style="zoom:50%;" /><p>从上图的示例代码（Kbuild.include 代码段）可以看出 build&#x3D;-f $(srctree)&#x2F;scripts&#x2F;Makefile.build obj，经过前面的分析可知，变量 srctree 为”.”，因此：  </p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">build=-f ./scripts/Makefile.build obj</span><br></pre></td></tr></table></figure><p>scripts_basic 展开以后如下：  </p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">scripts_basic:</span></span><br><span class="line">    @make -f ./scripts/Makefile.build obj=scripts/basic <span class="comment"># 也可以没有@，视配置而定</span></span><br><span class="line">    @rm -f . tmp_quiet_recordmcount <span class="comment">#也可以没有@</span></span><br></pre></td></tr></table></figure><p>scripts_basic 会调用文件.&#x2F;scripts&#x2F;Makefile.build  这个后边会再分析。</p>
              </div>
            </details>

<p>接着回到继续看上边顶层Makefile中的%config 处，内容如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">%config: scripts_basic outputmakefile FORCE</span></span><br><span class="line">	<span class="variable">$(Q)</span><span class="variable">$(MAKE)</span> <span class="variable">$(build)</span>=scripts/kconfig <span class="variable">$@</span></span><br></pre></td></tr></table></figure>

<p>将命令展开就是  :</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig</span><br></pre></td></tr></table></figure>

<p>同样也跟文件.&#x2F;scripts&#x2F;Makefile.build 有关，我们后面再分析此文件。使用如下命令配置 uboot，并观察其配置过程：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig </span><br></pre></td></tr></table></figure>

<p>然后就可以看到如下配置过程：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730134520374.png" alt="image-20230730134520374" style="zoom:50%;" />

<p>（1）scripts_basic 目标对应的命令</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/basic</span><br></pre></td></tr></table></figure>

<p>（2） %config 目标对应的命令</p>
 <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig </span><br></pre></td></tr></table></figure>

<h2 id="2-Makefile-build-脚本分析"><a href="#2-Makefile-build-脚本分析" class="headerlink" title="2. Makefile.build 脚本分析  "></a><font size=3>2. Makefile.build 脚本分析  </font></h2><p>从前边知道“ make xxx_defconfig“配置 uboot 的时候如下两行命令会执行脚本scripts&#x2F;Makefile.build：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/basic</span><br><span class="line">@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig  </span><br></pre></td></tr></table></figure>

<h3 id="2-1-scripts-basic-目标对应的命令"><a href="#2-1-scripts-basic-目标对应的命令" class="headerlink" title="2.1  scripts_basic 目标对应的命令  "></a><font size=3>2.1  scripts_basic 目标对应的命令  </font></h3><h4 id="2-1-1-8-17行"><a href="#2-1-1-8-17行" class="headerlink" title="2.1.1 8~17行"></a><font size=3>2.1.1 8~17行</font></h4><p>scripts_basic 目标对应的命令为： @make -f .&#x2F;scripts&#x2F;Makefile.build obj&#x3D;scripts&#x2F;basic。打开文件 scripts&#x2F;Makefile.build，有如下代码：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730134805520.png" alt="image-20230730134805520" style="zoom:50%;" />

<p>第 9 行定义了变量 prefix 值为 tpl。</p>
<p>第 10 行定义了变量 src，这里用到了函数 patsubst，此行代码展开后为：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">patsubst</span> tpl/%,%, scripts/basic)</span></span><br></pre></td></tr></table></figure>

<p>patsubst 是替换函数，格式如下：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">patsubst</span> &lt;pattern&gt;,&lt;replacement&gt;,&lt;text&gt;)</span></span><br></pre></td></tr></table></figure>

<p>此函数用于在 text 中查找符合 pattern 的部分，如果匹配的话就用 replacement 替换掉。pattenr 是可以包含通配符“%”，如果 replacement 中也包含通配符“%”，那么 replacement 中的这个“%”将是 pattern 中的那个“%”所代表的字符串。函数的返回值为替换后的字符串。因此，第 10 行就是在“scripts&#x2F;basic”中查找符合“tpl&#x2F;%”的部分，然后将“tpl&#x2F;”取消掉，但是“scripts&#x2F;basic”没有“tpl&#x2F;”，所以 src&#x3D; scripts&#x2F;basic。  </p>
<p>第 11 行判断变量 obj 和 src 是否相等，相等的话条件成立，很明显，此处条件成立。</p>
<p>第 12 行和第 9 行一样，只是这里处理的是“spl”，“scripts&#x2F;basic”里面也没有“spl&#x2F;”，所以src 继续为 scripts&#x2F;basic。</p>
<p>第 15 行因为变量 obj 和 src 相等，所以 prefix&#x3D;.。  </p>
<h4 id="2-1-2-56-59行"><a href="#2-1-2-56-59行" class="headerlink" title="2.1.2 56~59行"></a><font size=3>2.1.2 56~59行</font></h4><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135048080.png" alt="image-20230730135048080" style="zoom:50%;" />

<p>将 kbuild-dir 展开后为：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">filter</span> /%, scripts/basic)</span>, scripts/basic, ./scripts/basic)</span><br></pre></td></tr></table></figure>

<p>因为没有以“ &#x2F; ”为开头的单词，所以$(filter &#x2F;%, scripts&#x2F;basic)的结果为空， kbuilddir&#x3D;.&#x2F;scripts&#x2F;basic。  </p>
<p>将 kbuild-file 展开后为：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">wildcard</span> ./scripts/basic/Kbuild)</span>, ./scripts/basic/Kbuild, ./scripts/basic/Makefile)</span><br></pre></td></tr></table></figure>

<p>因为 scrpts&#x2F;basic 目录中没有 Kbuild 这个文件，所以 kbuild-file&#x3D; .&#x2F;scripts&#x2F;basic&#x2F;Makefile。最后将 59 行展开，即：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">include</span> ./scripts/basic/Makefile</span><br></pre></td></tr></table></figure>

<p>也就是读取 scripts&#x2F;basic 下面的 Makefile 文件。</p>
<h4 id="2-1-3-116-119行"><a href="#2-1-3-116-119行" class="headerlink" title="2.1.3 116~119行"></a><font size=3>2.1.3 116~119行</font></h4><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135331282.png" alt="image-20230730135331282" style="zoom:50%;" />

<p>__build 是默认目标，因为命令“@make -f .&#x2F;scripts&#x2F;Makefile.build obj&#x3D;scripts&#x2F;basic”没有指定目标，所以会使用到默认目标： __build。在顶层 Makefile 中， KBUILD_BUILTIN 为 1，KBUILD_MODULES 为 0，因此展开后目标__build 为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">__build:$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) <span class="variable">$(always)</span></span></span><br><span class="line">	@:  </span><br></pre></td></tr></table></figure>

<p>可以看出目标__build 有 5 个依赖： builtin-target、 lib-target、 extra-y、 subdir-ym 和 always。这 5 个依赖的具体内容我们就不通过源码来分析了，直接在 scripts&#x2F;Makefile.build 中输入图所示内容，将这 5 个变量的值打印出来：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135605771.png" alt="image-20230730135605771" style="zoom:50%;" />

<p>执行以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig </span><br></pre></td></tr></table></figure>

<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730135721373.png" alt="image-20230730135721373" style="zoom:50%;" />

<p>从上图可以看出，只有 always 有效，因此__build 最终为：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">__build: scripts/basic/fixdep</span></span><br><span class="line">	@:</span><br></pre></td></tr></table></figure>

<p>__build 依赖于 scripts&#x2F;basic&#x2F;fixdep，所以要先编译 scripts&#x2F;basic&#x2F;fixdep.c，生成 fixdep，前面已经读取了 scripts&#x2F;basic&#x2F;Makefile 文件。综上所述， scripts_basic 目标的作用就是编译出 scripts&#x2F;basic&#x2F;fixdep 这个软件。  </p>
<h3 id="2-2-config-目标对应的命令"><a href="#2-2-config-目标对应的命令" class="headerlink" title="2.2 %config 目标对应的命令  "></a><font size=3>2.2 %config 目标对应的命令  </font></h3><p>%config 目 标 对 应 的 命 令 为 ： </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/kconfigxxx_defconfig</span><br></pre></td></tr></table></figure>

<p>各个变量值如下：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">src= scripts/kconfig</span><br><span class="line">kbuild-dir = ./scripts/kconfig</span><br><span class="line">kbuild-file = ./scripts/kconfig/Makefile</span><br><span class="line"><span class="keyword">include</span> ./scripts/kconfig/Makefile</span><br></pre></td></tr></table></figure>

<p>可以看出， Makefilke.build 会读取 scripts&#x2F;kconfig&#x2F;Makefile 中的内容，此文件有如下所示内容：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140006404.png" alt="image-20230730140006404" style="zoom:50%;" />

<p>目标%_defconfig 刚好和我们输入的 xxx_defconfig 匹配，所以会执行这条规则。依赖为$(obj)&#x2F;conf，展开后就是 scripts&#x2F;kconfig&#x2F;conf。接下来就是检查并生成依赖 scripts&#x2F;kconfig&#x2F;conf。conf 是主机软件，到这里我们就打住，不要纠结 conf 是怎么编译出来的，否则就越陷越深，太绕了，像 conf 这种主机所使用的工具类软件我们一般不关心它是如何编译产生的。如果一定要看是 conf 是怎么生成的，可以输入如下命令重新配置 uboot，在重新配置 uboot 的过程中就会输出 conf 编译信息。  </p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig </span><br></pre></td></tr></table></figure>

<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140144991.png" alt="image-20230730140144991" style="zoom:50%;" />

<p>得到 scripts&#x2F;kconfig&#x2F;conf 以后就要执行目标%_defconfig 的命令：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(Q)</span><span class="variable">$&lt;</span> <span class="variable">$(silent)</span> --defconfig=arch/<span class="variable">$(SRCARCH)</span>/configs/<span class="variable">$@</span> <span class="variable">$(Kconfig)</span></span><br></pre></td></tr></table></figure>

<p>相关的变量值如下：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">silent=-s 或为空</span><br><span class="line">SRCARCH=..</span><br><span class="line">Kconfig=Kconfig</span><br></pre></td></tr></table></figure>

<p>将其展开就是 :</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@ scripts/kconfig/conf --defconfig=arch/../configs/xxx_defconfig Kconfig</span><br></pre></td></tr></table></figure>

<p>上述命令用到了 xxx_defconfig 文件，比如 mx6ull_14x14_evk_emmc_defconfig 。这里会将mx6ull_14x14_evk_emmc_defconfig  中的配置输出到.config 文件中，最终生成 uboot 根目录下的.config 文件。  </p>
<h2 id="3-过程总结"><a href="#3-过程总结" class="headerlink" title="3. 过程总结"></a><font size=3>3. 过程总结</font></h2><p>这个就是命令 make xxx_defconfig 执行流程 ：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140440227.png" alt="image-20230730140440227" style="zoom:50%;" />

<h1 id="二、-make过程分析"><a href="#二、-make过程分析" class="headerlink" title="二、 make过程分析"></a><font size=3>二、 make过程分析</font></h1><h2 id="1-目标"><a href="#1-目标" class="headerlink" title="1. 目标"></a><font size=3>1. 目标</font></h2><p>配置好 uboot 以后就可以直接 make 编译了，因为没有指明目标，所以会使用默认目标，主Makefile 中的默认目标如下：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730140953313.png" alt="image-20230730140953313" style="zoom:50%;" />

<p>目标_all 又依赖于 all，如下所示 ：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141035174.png" alt="image-20230730141035174" style="zoom:50%;" />

<p>如果 KBUILD_EXTMOD 为空的话 _all 依赖于 all 。这里不编译模块，所 以KBUILD_EXTMOD 肯定为空， _all 的依赖就是 all。在主 Makefile 中 all 目标规则如下：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141153467.png" alt="image-20230730141153467" style="zoom:50%;" />

<p>从 802 行可以看出， all 目标依赖$(ALL-y)，而在顶层 Makefile 中， ALL-y 如下  :</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141403808.png" alt="image-20230730141403808" style="zoom:50%;" />

<p>可以看出， ALL-y 包含 u-boot.srec、 u-boot.bin、 u-boot.sym、System.map、 u-boot.cfg 和 binary_size_check 这几个文件。根据 uboot 的配置情况也可能包含其他的文件，比如：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ALL-<span class="variable">$(CONFIG_ONENAND_U_BOOT)</span> += u-boot-onenand.bin</span><br></pre></td></tr></table></figure>

<p>CONFIG_ONENAND_U_BOOT 就是 uboot 中跟 ONENAND 配置有关的，如果我们使能了ONENAND，那么在.config 配置文件中就会有“CONFIG_ONENAND_U_BOOT&#x3D;y”这一句。相当于 CONFIG_ONENAND_U_BOOT 是个变量，这个变量的值为“y”，所以展开以后就是：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ALL-y += u-boot-onenand.bin</span><br></pre></td></tr></table></figure>

<p>这个就是.config 里面的配置参数的含义，这些参数其实都是变量，后面跟着变量值，会在顶层 Makefile 或者其他 Makefile 中调用这些变量。</p>
<h2 id="2-u-boot-bin"><a href="#2-u-boot-bin" class="headerlink" title="2. u-boot.bin"></a><font size=3>2. u-boot.bin</font></h2><p>ALL-y 里面有个 u-boot.bin，这个就是我们最终需要的 uboot 二进制可执行文件，所作的所有工作就是为了它。在顶层 Makefile 中找到 u-boot.bin 目标对应的规则，如下所示：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730141540677.png" alt="image-20230730141540677" style="zoom:50%;" />

<p>第 825 行判断 CONFIG_OF_SEPARATE 是否等于 y，如果相等，那条件就成立，在.config中搜索“CONFIG_OF_SEPARAT”，没有找到，说明条件不成立。</p>
<p>第 832 行就是目标 u-boot.bin 的规则，目标 u-boot.bin 依赖于 u-boot-nodtb.bin，命令为$(call if_changed,copy) ， 这 里 调 用 了 if_changed ， if_changed 是 一 个 函 数 ， 这个函数在 scripts&#x2F;Kbuild.include 中有定义，而顶层 Makefile 中会包含 scripts&#x2F;Kbuild.include 文件，这个前面已经说过了。  if_changed 在 Kbuild.include 中的定义如下：</p>
<details class="folding-tag" blue><summary> 点击查看if_changed 定义 </summary>
              <div class='content'>
              <figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">226 <span class="comment">###</span></span><br><span class="line">227 <span class="comment"># if_changed      - execute command if any prerequisite is newer than</span></span><br><span class="line">228 <span class="comment">#                   target, or command line has changed</span></span><br><span class="line">229 <span class="comment"># if_changed_dep  - as if_changed, but uses fixdep to reveal dependencies</span></span><br><span class="line">230 <span class="comment">#                   including used config symbols</span></span><br><span class="line">231 <span class="comment"># if_changed_rule - as if_changed but execute rule instead</span></span><br><span class="line">232 <span class="comment"># See Documentation/kbuild/makefiles.txt for more info</span></span><br><span class="line">233 </span><br><span class="line">234 <span class="keyword">ifneq</span> (<span class="variable">$(KBUILD_NOCMDDEP)</span>,1)</span><br><span class="line">235 <span class="comment"># Check if both arguments has same arguments. Result is empty string if equal.</span></span><br><span class="line">236 <span class="comment"># User may override this check using make KBUILD_NOCMDDEP=1</span></span><br><span class="line">237 arg-check = <span class="variable">$(<span class="built_in">strip</span> $(<span class="built_in">filter</span>-out $(cmd_$(1)</span>), $(cmd_<span class="variable">$@</span>)) \</span><br><span class="line">238                     <span class="variable">$(<span class="built_in">filter</span>-out $(cmd_<span class="variable">$@</span>)</span>,   $(cmd_$(1))) )</span><br><span class="line">239 <span class="keyword">else</span></span><br><span class="line">240 arg-check = <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">strip</span> $(cmd_<span class="variable">$@</span>)</span>),,1)</span><br><span class="line">241 <span class="keyword">endif</span></span><br><span class="line">242 </span><br><span class="line">243 <span class="comment"># Replace &gt;$&lt; with &gt;$$&lt; to preserve $ when reloading the .cmd file</span></span><br><span class="line">244 <span class="comment"># (needed for make)</span></span><br><span class="line">245 <span class="comment"># Replace &gt;#&lt; with &gt;\#&lt; to avoid starting a comment in the .cmd file</span></span><br><span class="line">246 <span class="comment"># (needed for make)</span></span><br><span class="line">247 <span class="comment"># Replace &gt;&#x27;&lt; with &gt;&#x27;\&#x27;&#x27;&lt; to be able to enclose the whole string in &#x27;...&#x27;</span></span><br><span class="line">248 <span class="comment"># (needed for the shell)</span></span><br><span class="line">249 make-cmd = <span class="variable">$(<span class="built_in">call</span> escsq,$(<span class="built_in">subst</span> \#,\\\#,$(<span class="built_in">subst</span> $$,$$$$,$(cmd_$(1)</span>))))</span><br><span class="line">250 </span><br><span class="line">251 <span class="comment"># Find any prerequisites that is newer than target or that does not exist.</span></span><br><span class="line">252 <span class="comment"># PHONY targets skipped in both cases.</span></span><br><span class="line">253 any-prereq = <span class="variable">$(<span class="built_in">filter</span>-out <span class="variable">$(PHONY)</span>,<span class="variable">$?</span>)</span> <span class="variable">$(<span class="built_in">filter</span>-out <span class="variable">$(PHONY)</span> $(<span class="built_in">wildcard</span> <span class="variable">$^</span>)</span>,<span class="variable">$^</span>)</span><br><span class="line">254 </span><br><span class="line">255 <span class="comment"># Execute command if command has changed or prerequisite(s) are updated.</span></span><br><span class="line">256 <span class="comment">#</span></span><br><span class="line">257 if_changed = <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">strip</span> $(any-prereq)</span> $(arg-check)),                       \</span><br><span class="line">258         @set -e;                                                             \</span><br><span class="line">259         $(echo-cmd) $(cmd_$(1));                                             \</span><br><span class="line">260         printf &#x27;%s\n&#x27; &#x27;cmd_<span class="variable">$@</span> := $(make-cmd)&#x27; &gt; $(dot-target).cmd)</span><br><span class="line">261 </span><br><span class="line"></span><br></pre></td></tr></table></figure><p>第 227 行为 if_changed 的描述，根据描述，在一些先决条件比目标新的时候，或者命令行有改变的时候， if_changed 就会执行一些命令。</p><p>第 257 行就是函数 if_changed， if_changed 函数引用的变量比较多，也比较绕，我们只需要知道它可以从 u-boot-nodtb.bin 生成 u-boot.bin 就行了。  </p>
              </div>
            </details>

<h2 id="3-u-boot-nodtb-bin"><a href="#3-u-boot-nodtb-bin" class="headerlink" title="3. u-boot-nodtb.bin"></a><font size=3>3. u-boot-nodtb.bin</font></h2><p>既然 u-boot.bin 依赖于 u-boot-nodtb.bin，那么肯定要先生成 u-boot-nodtb.bin 文件，顶层Makefile 中相关代码如下：    </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142244988.png" alt="image-20230730142244988" style="zoom:50%;" />

<p>目标 u-boot-nodtb.bin 又依赖于 u-boot，顶层 Makefile 中 u-boot 相关规则如下：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142326658.png" alt="image-20230730142326658" style="zoom:50%;" />

<p>目标 u-boot 依赖于 u-boot_init、 u-boot-main 和 u-boot.lds， u-boot_init 和 u-boot-main 是两个变量，在顶层 Makefile 中有定义，值如下：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142402882.png" alt="image-20230730142402882" style="zoom:50%;" />

<p>$(head-y)跟 CPU 架构有关，我们使用的是 ARM 芯片，所以 head-y 在 arch&#x2F;arm&#x2F;Makefile 中被指定为：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">head-y := arch/arm/cpu/<span class="variable">$(CPU)</span>/start.o</span><br></pre></td></tr></table></figure>

<p>根据《LV05-01-uboot-06-顶层Makefile-01-基础分析》——六、变量分析一小节的分析，我们知道 CPU&#x3D;armv7，因此 head-y 展开以后就是：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">head-y := arch/arm/cpu/armv7/start.o</span><br></pre></td></tr></table></figure>

<p>所以就有：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">u-boot-init= arch/arm/cpu/armv7/start.o</span><br></pre></td></tr></table></figure>

<p>$(libs-y)在顶层 Makefile 中被定义为 uboot 所有子目录下 build-in.o 的集合，代码如下：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730142755244.png" alt="image-20230730142755244" style="zoom:50%;" />

<p>从上面的代码可以看出， libs-y 都是 uboot 各子目录的集合，最后：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">libs-y := <span class="variable">$(<span class="built_in">patsubst</span> %/, %/built-in.o, $(libs-y)</span>)</span><br></pre></td></tr></table></figure>

<p>这里调用了函数 patsubst，将 libs-y 中的“&#x2F;”替换为”&#x2F;built-in.o”，比如“drivers&#x2F;dma&#x2F;”就变为了“drivers&#x2F;dma&#x2F;built-in.o”，相当于将 libs-y 改为所有子目录中 built-in.o 文件的集合。那么 uboot-main 就等于所有子目录中 built-in.o 的集合。  </p>
<p>这个规则就相当于将以 u-boot.lds 为链接脚本，将 arch&#x2F;arm&#x2F;cpu&#x2F;armv7&#x2F;start.o 和各个子目录下的 built-in.o 链接在一起生成 u-boot。u-boot.lds 的规则如下：  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143037482.png" alt="image-20230730143037482" style="zoom:50%;" />

<p>接下来的重点就是各子目录下的 built-in.o 是怎么生成的，以 drivers&#x2F;gpio&#x2F;built-in.o 为例，在drivers&#x2F;gpio&#x2F;目录下会有个名为.built-in.o.cmd 的文件： </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143302250.png" alt="image-20230730143302250" style="zoom:50%;" />

<p>此文件内容如下： </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cmd_drivers/gpio/built-in.o :=  arm-linux-gnueabihf-ld.bfd   -r -o drivers/gpio/built-in.o drivers/gpio/mxc_gpio.o</span><br></pre></td></tr></table></figure>

<p>从命令“cmd_drivers&#x2F;gpio&#x2F;built-in.o”可以看出， drivers&#x2F;gpio&#x2F;built-in.o 这个文件是使用 ld 命令由文件 drivers&#x2F;gpio&#x2F;mxc_gpio.o 生成而来的，mxc_gpio.o 是 mxc_gpio.c 编译生成的.o 文件，这个是 NXP 的 I.MX 系列的 GPIO 驱动文件。这里用到了 ld 的“-r”参数，参数含义如下：-r –relocateable: 产生可重定向的输出，比如，产生一个输出文件它可再次作为‘ld’ 的输入，这经常被叫做“部分链接”，当我们需要将几个小的.o 文件链接成为一个.o 文件的时候，需要使用此选项。  </p>
<p>最终将各个子目录中的 built-in.o 文件链接在一起就形成了 u-boot，使用如下命令编译 uboot就可以看到链接的过程：  </p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig </span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16</span><br></pre></td></tr></table></figure>

<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143707862.png" alt="image-20230730143707862" style="zoom:50%;" />

<p>可以看出最终是用 arm-linux-gnueabihf-ld.bfd 命令将 arch&#x2F;arm&#x2F;cpu&#x2F;armv7&#x2F;start.o 和其他众多的 built_in.o 链接在一起，形成 u-boot。目标 all 除了 u-boot.bin 以外还有其他的依赖，比如 u-boot.srec 、 u-boot.sym 、 System.map、u-boot.cfg 和 binary_size_check 等等，这些依赖的生成方法和 u-boot.bin 很类似，这里就不再详细说明了。  </p>
<h2 id="4-过程总结"><a href="#4-过程总结" class="headerlink" title="4. 过程总结"></a><font size=3>4. 过程总结</font></h2><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/LV05-01-uboot-06-%E9%A1%B6%E5%B1%82Makefile-02-%E7%9B%B8%E5%85%B3%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/img/image-20230730143850408.png" alt="image-20230730143850408" style="zoom:50%;" />

<p>make xxx_defconfig： 用于配置 uboot，这个命令最主要的目的就是生成.config 文件。<br>make：用于编译 uboot，这个命令的主要工作就是生成二进制的 u-boot.bin 文件和其他的一些与 uboot 有关的文件，比如 u-boot.imx 等等。  </p>

    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/5c91070d.html">LV05-01-uboot-06-顶层Makefile-02-相关过程分析</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2023年09月08日 - 19:23</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/5c91070d.html" title="LV05-01-uboot-06-顶层Makefile-02-相关过程分析">https://sumumm.github.io/post/5c91070d.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/ALPHA-LV05-uboot%E4%B8%8E%E5%86%85%E6%A0%B8/" rel="tag"><i class="fa fa-tag"></i> (ALPHA)LV05-uboot与内核</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/b353fdae.html" rel="prev" title="LV05-01-uboot-07-uboot移植">
                  <i class="fa fa-angle-left"></i> LV05-01-uboot-07-uboot移植
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/aadd7195.html" rel="next" title="LV05-01-uboot-06-顶层Makefile-01-基础分析">
                  LV05-01-uboot-06-顶层Makefile-01-基础分析 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
